import argparse
import random
import json
import pymysql
import copy
import os, sys, re, time
from datetime import date

CVSAMPLE_DICT = {
        'id': -1, 'sample_id': -1, 'medical_id': -1, 'hospital': -1, 'name': -1, 'age': -1,
        'cellphone': -1, 'menses_last': -1, 'menses_no': -1, 'status': -1, 'deliv_dep': -1,
        'deliv_doc': -1, 'deliv_time': -1, 'recv_time': -1, 'register': -1, 'inhos_zone': -1,
        'inhos_room': -1, 'inhos_bed': -1, 'report_doctor': -1, 'result': -1, 'review_result': -1,
        'auto_result': -1, 'doctor_result': -1, 'idea': -1, 'sex': -1, 'audit_doctor': -1,
        'audit_time': -1, 'img': -1, 'img_2': -1, 'auto_conclude': -1, 'doctor_conclude': -1,
        'treat_advice': -1, 'scan_id': -1, 'medical_attitude': -1, 'cell_counts': -1, 'neck_cell': -1,
        'metaplastic_cell': -1, 'inflamation_degree': -1, 'trichmonad': -1, 'mold': -1, 'herpes': -1,
        'HPV': -1}

BMSAMPLE_DICT = {
        'id': -1, 'pathology_id': -1, 'hospital_id': -1, 'sample_type': -1, 'name': -1,
        'status': -1, 'sample_create_time': -1, 'hospital_id_type': -1, 'gender': -1,
        'age': -1, 'bed_ward': -1, 'bed_room': -1, 'bed_id': -1, 'send_hospital': -1,
        'department': -1, 'send_doctor': -1, 'doctor_phone': -1, 'bs_sample_id': -1,
        'bm_sample_id': -1, 'bm_type': -1, 'bm_gather_sample_time': -1, 'bm_gather_person': -1,
        'bm_receive_sample_time': -1, 'bm_receive_person': -1, 'bs_type': -1,
        'bs_gather_sample_time': -1, 'bs_gather_person': -1, 'bs_receive_sample_time': -1,
        'bs_receive_person': -1, 'validate_sample': -1, 'test_period': -1, 'clinical_diagnose': -1,
        'sign': -1, 'protocol': -1, 'chemotherapy': -1, 'is_matastasis': -1, 'wbc': -1,
        'neutrophil': -1, 'lymphocyte': -1, 'monocytes': -1, 'eosinophil': -1, 'basophil': -1,
        'rbc': -1, 'hb': -1, 'plt': -1, 'rtc': -1, 'primitive_cell': -1, 'bmcytology': -1,
        'form_description': -1, 'diagnosis_opinion': -1, 'image_10': -1, 'image_100': -1,
        'is_scan': -1, 'scan_id': -1, 'count_list': -1, 'report_doctor': -1, 'report_time': -1,
        'audit_doctor': -1, 'sample_position': -1, 'report_status': -1, 'sample_size': -1}

def randomPhone():
    phoneHead = ('13', '15', '18', '17') 
    head = phoneHead[random.choice(range(len(phoneHead)))]
    for i in range(11 - len(head)):
        head += str(random.randint(0, 9))
    return head

def randomName():
    firstName = ("赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻水云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳鲍史唐费岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅卞齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧计成戴宋茅庞熊纪舒屈项祝董粱杜阮席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田胡凌霍万柯卢莫房缪干解应宗丁宣邓郁单杭洪包诸左石崔吉龚程邢滑裴陆荣翁荀羊甄家封芮储靳邴松井富乌焦巴弓牧隗山谷车侯伊宁仇祖武符刘景詹束龙叶幸司韶黎乔苍双闻莘劳逄姬冉宰桂牛寿通边燕冀尚农温庄晏瞿茹习鱼容向古戈终居衡步都耿满弘国文东殴沃曾关红游盖益桓公晋楚闫")
    girl = "秀娟英华慧巧美娜静淑惠珠翠雅芝玉萍红娥玲芬芳燕彩春菊兰凤洁梅琳素云莲真环雪荣爱妹霞香月莺媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧璐娅琦晶妍茜秋珊莎锦黛青倩婷姣婉娴瑾颖露瑶怡婵雁蓓纨仪荷丹蓉眉君琴蕊薇菁梦岚苑婕馨瑗琰韵融园艺咏卿聪澜纯毓悦昭冰爽琬茗羽希宁欣飘育滢馥筠柔竹霭凝晓欢霄枫芸菲寒伊亚宜可姬舒影荔枝思丽"
    name = "中笑贝凯歌易仁器义礼智信友上都卡被好无九加电金马钰玉忠孝"

    first_name = firstName[random.choice(range(len(firstName)))]
    mid_name = ''
    girl_name = girl[random.choice(range(len(girl)))]
    if random.choice(range(2)) > 0:
        mid_name = name[random.choice(range(len(name)))]
    return first_name + mid_name + girl_name

def connDB():
    with open('./cfg.json', 'r') as fp:
        cfg = json.load(fp)
        conn = pymysql.connect(
                host = cfg['db']['host'],
                port = cfg['db']['port'],
                user = cfg['db']['user'],
                password = cfg['db']['password'],
                charset = 'utf8'
                )
        return conn
    return None

def genInsertSql(tableName, sampleDict):
    keys, vals = [], []
    for k, v in sampleDict.items():
        if v != -1:
            keys.append(k)
            if type(v) == str:
                vals.append(f'"{v}"')
            else:
                vals.append(str(v))
    keyStr = ','.join(keys)
    valStr = ','.join(vals)

    return 'insert into {} ({}) values ({});'.format(tableName, keyStr, valStr)

def createCVSample(scanId, cursor, status):
    hospitals = ['湖北省中医院', '中南医院']
    sampleId = scanId[:-15]
    name = randomName()
    phone = randomPhone()

    isScan = 'False'
    if status == 1: # 待扫描
        isScan = 'False'
    elif status == 2: # 待诊断
        isScan = 'True'

    global CVSAMPLE_DICT
    d = date.today()
    pDict = copy.deepcopy(CVSAMPLE_DICT)
    pDict["sample_id"] = sampleId
    pDict["medical_id"] = sampleId
    pDict["scan_id"] = scanId
    pDict["name"] = name
    pDict["age"] = str(random.randint(20, 75))
    pDict["cellphone"] = phone
    pDict["menses_last"] = d.strftime('%Y-%m-%d')
    pDict["menses_no"] = 0
    pDict["status"] = status
    pDict["hospital"] = hospitals[0]
    pDict["deliv_dep"] = random.randint(1, 5)
    pDict["deliv_doc"] = random.randint(7, 9)
    pDict["deliv_time"] = d.strftime('%Y-%m-%d %H:%M')
    pDict["recv_time"] = d.strftime('%Y-%m-%d %H:%M')
    pDict["register"] = random.choice(["2", "3", "4"])
    pDict["inhos_zone"] = str(random.randint(10, 20))
    pDict["inhos_room"] = str(random.randint(10, 20))
    pDict["inhos_bed"] = str(random.randint(10, 90))
    sql = genInsertSql('sample', pDict)
    print(sql)
    cursor.execute(sql)

    oDict = copy.deepcopy(CVSAMPLE_DICT)
    oDict["sample_id"] = sampleId
    oDict["abnormal_blood"] = 0
    oDict["HPV_infect"] = 0
    oDict["IUD"] = 0
    oDict["acyeterion"] = 0
    oDict["estrogen"] = 0
    oDict["chemotherapy"] = 0
    oDict["pregnant"] = 0
    oDict["birth_4month"] = 0
    oDict["lactation"] = 0
    oDict["uterus_cut"] = 0
    oDict["cervical_cut"] = 0
    oDict["uterus_cutall"] = 0
    oDict["other_treat"] = 0
    oDict["other_treat_t"] = ""
    oDict["treat_history"] = ""
    oDict["clinical_find"] = ""
    sql = genInsertSql('sample_other', oDict)
    print(sql)
    cursor.execute(sql)

def createBMSample(scanId, cursor, status):
    hospitals = ['中纪', '湖北省中医院', '中南医院']
    department = ['医学部']
    sampleId = scanId[:-15]
    name = randomName()
    dname = randomName()
    phone = randomPhone()

    # status:
    #  1, 待高倍扫
    #  2, 待诊断
    #  3, 待复核
    #  4, 已复核
    isScan = 'False'
    reportStatus = 2
    if status == 1: # 待高倍扫描
        isScan = 'True'
        reportStatus = 2
    elif status == 2: # 待诊断
        isScan = 'True'
        reportStatus = 2
    elif status == 0: # 待低倍扫描
        isScan = 'False'
        reportStatus = 2

    global BMSAMPLE_DICT
    d = date.today()
    pDict = copy.deepcopy(BMSAMPLE_DICT)
    pDict['bm_sample_id'] = sampleId
    pDict['pathology_id'] = sampleId
    pDict['hospital_id'] = sampleId
    pDict['scan_id'] = scanId
    pDict['name'] = name
    pDict['age'] = str(random.randint(20, 75))
    pDict['status'] = status
    pDict['report_status'] = reportStatus
    pDict['sample_position'] = 1
    pDict['sample_size'] = 1

    pDict['sample_type'] = '骨髓涂片'
    pDict['sample_create_time'] = d.strftime('%Y-%m-%d %H:%M')
    pDict['hospital_id_type'] = 0
    pDict['gender'] = 0
    pDict['send_hospital'] = hospitals[0]
    pDict['department'] = department[0]
    pDict['send_doctor'] = dname

    pDict['bm_type'] = 1
    pDict['bm_gather_sample_time'] = d.strftime('%Y-%m-%d %H:%M')
    pDict['bm_receive_sample_time'] = d.strftime('%Y-%m-%d %H:%M')
    pDict['bs_gather_sample_time'] = d.strftime('%Y-%m-%d %H:%M')
    pDict['bs_receive_sample_time'] = d.strftime('%Y-%m-%d %H:%M')
    pDict['validate_sample'] = str([0, 0, 0, 0])
    pDict['test_period'] = str([0, 0, 0, 0, ''])
    pDict['sign'] = str([0, 0, 0, 0, 0, 0, 0, 0, ''])
    pDict['is_matastasis'] = str([0, 1])

    sql = genInsertSql('sample', pDict)
    print(sql)
    cursor.execute(sql)

def importCVSample(sliceDir):
    db = 'tct'
    conn = connDB()
    cursor = None
    if conn is not None:
        cursor = conn.cursor()
        cursor.execute(f'use {db};')

    if cursor is None:
        sys.exit(0)

    lstSampleId = []
    cursor.execute(f'select sample_id from sample;')
    for row in cursor.fetchall():
        lstSampleId.append(row[0])

    count = 0
    paths = os.listdir(sliceDir)
    dictScanId = {}
    for slicePath in paths:
        scanId = re.search(r'.+_\d{14}$', os.path.basename(slicePath))
        if scanId:
            scanId = scanId.group()
            sampleId = scanId[:-15]
            if sampleId not in lstSampleId:
                if os.path.isfile(os.path.join(sliceDir, scanId, '20/00_NM/zjscaninf.json')) \
                        or os.path.isfile(os.path.join(sliceDir, scanId, '40/00_NM/zjscaninf.json')):
                    status = 2
                    dictScanId[sampleId] = (scanId, status)

    for scanId, status in dictScanId.values():
        createCVSample(scanId, cursor, status)

    if len(dictScanId) > 0:
        ZJ_DIR = '{}/prj/ZJ'.format(os.getenv('HOME'))
        srcDir = sliceDir
        destDir = os.path.join(ZJ_DIR, 'dat1/CV')
        if srcDir != destDir:
            timeStr = time.strftime('%y%m%d%H%M%S', time.gmtime())
            os.system(f'mv {destDir} {destDir}_{timeStr}')
            os.system(f'ln -s {srcDir} {destDir}')
    print('import sample {}'.format(len(dictScanId)))
    conn.commit()

def importBMSample(sliceDir):
    db = 'bs'
    conn = connDB()
    cursor = None
    if conn is not None:
        cursor = conn.cursor()
        cursor.execute(f'use {db};')

    if cursor is None:
        sys.exit(0)

    lstSampleId = []
    cursor.execute(f'select bm_sample_id from sample;')
    for row in cursor.fetchall():
        lstSampleId.append(row[0])

    # status:
    #  0, 待低倍扫
    #  1, 待高倍扫
    #  2, 待诊断
    #  3, 待复核
    #  4, 已复核
    count = 0
    paths = os.listdir(sliceDir)
    dictScanId = {}
    for slicePath in paths:
        scanId = re.search(r'.+_\d{14}$', os.path.basename(slicePath))
        if scanId:
            scanId = scanId.group()
            sampleId = scanId[:-15]
            if sampleId not in lstSampleId:
                status = 0
                if os.path.isdir(os.path.join(sliceDir, scanId, '100')):
                    status = 2
                elif os.path.isdir(os.path.join(sliceDir, scanId, '10')):
                    status = 1
                dictScanId[sampleId] = (scanId, status)

    for scanId, status in dictScanId.values():
        createBMSample(scanId, cursor, status)

    if len(dictScanId) > 0:
        ZJ_DIR = '{}/prj/ZJ'.format(os.getenv('HOME'))
        srcDir = sliceDir
        destDir = os.path.join(ZJ_DIR, 'dat1/BM')
        if srcDir != destDir:
            timeStr = time.strftime('%y%m%d%H%M%S', time.gmtime())
            os.system(f'mv {destDir} {destDir}_{timeStr}')
            os.system(f'ln -s {srcDir} {destDir}')
    print('import sample {}'.format(len(dictScanId)))
    conn.commit()

def clearSample(sliceType):
    db = ''
    if sliceType == 'CV':
        db = 'tct'
    elif sliceType == 'BM':
        db = 'bs'

    conn = connDB()
    cursor = None
    if conn is not None:
        cursor = conn.cursor()
        cursor.execute(f'use {db};')

    if cursor is None:
        sys.exit(0)

    if sliceType == 'CV':
        cursor.execute(f'delete from sample where 1=1;')
        cursor.execute(f'delete from sample_other where 1=1;')
    elif sliceType == 'BM':
        cursor.execute(f'delete from sample where 1=1;')
    print('clear {}.'.format(db))
    conn.commit()

if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-s', '--sliceType', default='CV', choices=['CV', 'BM'], help='sliceType: [CV, BM]')
    parser.add_argument('-d', '--sliceDir', default='.', help='slice dir.')
    args = parser.parse_args()

    if args.sliceType == 'CV':
        importCVSample(args.sliceDir)
    elif args.slicetType == 'BM':
        importBMSample(args.sliceDir)
